#include <stdint.h>
#include <stddef.h>

#define CRC32_POLYNOMIAL 0xedb88320L  // CRC32多项式
uint32_t crc32_table[256];
void crc_32_table_init()
{
  uint32_t crc;
  for (int i = 0; i < 256; i++) {
    crc = i;
    for (int j = 8; j > 0; j--) {
      if (crc & 1) {
        crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
      } else {
        crc >>= 1;
      }
    }
    crc32_table[i] = crc;
  }
}
uint32_t crc_32(const unsigned char *buf, size_t len)
{
  uint32_t crc = 0;
  crc = ~crc;
  for (size_t i = 0; i < len; i++) {
    uint8_t table_index = (crc ^ buf[i]) & 0xff;
    crc = (crc >> 8) ^ crc32_table[table_index];
  }
  return ~crc;
}
#define POLYNOMIAL 0x11021  // CRC-16/CCITT-FALSE 多项式
#define INITIAL_VALUE 0xFFFF  // 初始值
#define FINAL_XOR_VALUE 0x0000  // 最终异或值

// CRC-16/CCITT-FALSE 计算函数
uint16_t crc_16_ccitt_false(uint8_t *data, size_t length)
{
  uint16_t crc = INITIAL_VALUE;

  for (size_t i = 0; i < length; i++) {
    crc ^= (data[i] << 8);  // 将字节移至 CRC 的高字节
    for (uint8_t j = 0; j < 8; j++) {  // 对每个字节的每一位进行计算
      if (crc & 0x8000) {  // 检查最高位
        crc = (crc << 1) ^ POLYNOMIAL;  // 左移并异或多项式
      } else {
        crc = crc << 1;  // 否则，仅左移
      }
    }
  }

  return crc ^ FINAL_XOR_VALUE;  // 最终异或
}
